/**
 * 封装axios请求模块
 */
// 1.导入axios及store
import axios from 'axios'
import store from '@/store'
import router from '../router';
import { Toast } from 'vant';
import jsonBig from 'json-bigint'

// 2.做环境切换
let baseURL = '';
if (process.env.NODE_ENV === 'development') {
  // baseURL = 'http://geek.itheima.net'; // 开发环境下
  baseURL = 'https://toutiao.itheima.net/'; // 开发环境下
} else if (process.env.NODE_ENV === 'production') {
  baseURL = 'https://toutiao.itheima.net/'; // 生产环境
}


// 3.自定义axios
const request = axios.create({
  baseURL: baseURL, // 请求基础路径
  timeout: 6000, // 请求超时时间
  // `transformResponse` 在传递给 then/catch 前，允许修改响应数据
  transformResponse: [function (data) {
    // 对发送的 data 进行任意转换处理
    try {
      // json-bigint可以处理数据中超出js安全整数的问题
      return jsonBig.parse(data)
    } catch (error) {
      return data;
    }
  }],
})

// 4.添加请求拦截器(请求会经过这里)
request.interceptors.request.use((config) => {
  // console.log(config);
  const { user } = store.state
  // config: 本次请求的请求配置对象
  if (user && user.token) {
    config.headers.Authorization = `Bearer ${user.token}`
  }
  return config
}, (error) => {
  console.log(error);
  return Promise.reject(error);
})

// 5.添加响应拦截器
request.interceptors.response.use((res) => {
  console.log('本次响应为:', res)
  // 2xx 范围内的状态码都会触发该函数。
  // 对响应数据处理
  return res.data.data
}, err => {
  // 超出 2xx 范围的状态码都会触发该函数
  console.log('响应失败,', err);
  // token过期处理
  // 如果响应码是401,则请求获取新的token
  if (err.response && err.response.status == 401) {
    // 校验是否有refresh_token
    const user = store.state.user;
    if (!user || !user.refresh_token) {
      router.push('/login')
      return;
    } else {
      // 如果有refresh_token，则请求获取新的 token
      axios({
        method: 'PUT',
        url: 'https://toutiao.itheima.net/v1_0/authorizations',
        headers: {
          Authorization: `Bearer ${user.refresh_token}`
        }
      }).then(res => {
        console.log('刷新token', res);
        // 如果获取成功，则把新的 token 更新到容器中
        store.commit('setUser', {
          token: res.data.data.token, // 最新获取的可用 token
          refresh_token: user.refresh_token // 还是原来的 refresh_token
        });
        // 把之前失败的用户请求继续发出去
        // config 是一个对象，其中包含本次失败请求相关的那些配置信息，例如 url、method 都有
        // return 把 request 的请求结果继续返回给发请求的具体位置
        console.log('err.config', err.config);
        return request(err.config);
      }).catch(err => {
        // 如果获取失败，直接跳转登录页
        console.log('请求刷新token失败', err);
        Toast.fail('请求刷新token失败')
        router.push('/login');
      })
    }
  }
  return Promise.reject(err)
})
export default request
